package gui;

import entities.Playlist;
import entities.Song;
import helpers.UIHelper;
import helpers.ValidationHelper;


// Διάλογος Διαχείρισης Λίστας Τραγουδιών
public class PlaylistForm extends javax.swing.JDialog {
    private String dialogResult = "Cancel";
    private final ValidationHelper validator = new ValidationHelper();
    

    public PlaylistForm(Playlist _entity) {
        initComponents();
        
        // Εμφάνισε το παράθυρο σαν modal και σε κέντρο σε σχέση με την parent form
        this.setModal(true);
        this.setLocationRelativeTo(this.getOwner());
        
        entity = _entity;
        
        updateControlsFromEntity();
    }
    
    // Constructor χωρίς ορίσματα που κάνει κλήση του παραπάνω constructor
    // με όρισμα νέο αντικείμενο
    public PlaylistForm() {
        this(new Playlist());
    }
    
    // Ενημέρωση των των controls από τα properties του entity
    private void updateControlsFromEntity(){
        // Αν το id του entity δεν είναι null, το αντικείμενο είναι persisted
        // οπότε αρχικοποιούμε τις τιμές των controls
        if (entity.getId() != null) {
            this.titleText.setText(entity.getName());
            this.dateTextField.setText(validator.getDF().format(entity.getCreationDate()));
            
            this.songList.clear();
            this.songList.addAll(entity.getSongList());
            getTotalDuration();
        }
    }
    
    // Ενημέρωση των properties του entity από τις τιμές των controls
    private void updateEntityFromControls() {
        entity.setName(titleText.getText());
        
        if (validator.isValidDate(this.dateTextField.getText())){
            entity.setCreationDate(validator.parseDate(this.dateTextField.getText()));
        }
        
        entity.setSongList(songList);
    }
    
    // Επιστρέφει το entity της φόρμας
    public Playlist getEntity()
    {
        updateEntityFromControls();
        return entity;
    }
    
    // Επιστρέφει την τρέχουσα τιμή του dialogResult (Save/Cancel)
    public String getDialogResult()
    {
        return this.dialogResult;
    }
    
    // Κλείνει το διάλογο αφού πρώτα κάνει τους απαραίτητους ελέγχους
    protected void closeDialog(String _dialogResult) {
        if (_dialogResult != null && !_dialogResult.isEmpty()){
            dialogResult = _dialogResult;
        }
        if ((this.dialogResult.equals("Save") && validateEntity()) || this.dialogResult.equals("Cancel")){
            this.dispose();
        }
    }
    
    // Έλεγχος εγκυρότητας δεδομένων πριν την αποθήκευση
    // με χρήση ενός managers.ValidationHelper
    protected boolean validateEntity(){
        validator.getRules().clear();
        validator.addDateRule(this.dateTextField.getText());
        validator.addRule(getTotalDuration() < 1800, "Η Λίστα πρέπει να έχει συνολική διάρκεια τουλάχιστον 30 λεπτά !");
        return validator.validateRules(this);
    }
    
    // Εύρεση συνολικής διάρκειας Λίστας
    protected int getTotalDuration() {
        int duration = 0;
        
        for (Song song : songList){
            duration += song.getDuration();
        }

        durationLabel.setText(String.format("%.1f λεπτά", ((double)duration/60)));
        
        return duration;
    }
    
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        entity = new entities.Playlist();
        em = java.beans.Beans.isDesignTime() ? null : javax.persistence.Persistence.createEntityManagerFactory("KLMRadioStationPU").createEntityManager();
        songQuery = java.beans.Beans.isDesignTime() ? null : em.createQuery("SELECT s FROM Song s where s.id = -1");
        songList = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : org.jdesktop.observablecollections.ObservableCollections.observableList(new java.util.LinkedList(songQuery.getResultList()));
        saveButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        titleText = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        dateTextField = new javax.swing.JFormattedTextField();
        jLabel6 = new javax.swing.JLabel();
        insertSongBtn = new javax.swing.JButton();
        deleteSongBtn = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        table = new javax.swing.JTable();
        jLabel1 = new javax.swing.JLabel();
        durationLabel = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Διαχείριση Λίστας Αναπαραγωγής");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        saveButton.setText("Αποθήκευση");
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });

        cancelButton.setText("Άκυρο");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        jLabel2.setText("Όνομα Λίστας");

        jLabel7.setText("Λίστα Τραγουδιών");

        dateTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.DateFormatter(new java.text.SimpleDateFormat("dd/MM/yyyy"))));

        jLabel6.setText("Ημερομηνία Ενημέρωσης");

        insertSongBtn.setText("Εισαγωγή Τραγουδιού");
        insertSongBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                insertSongBtnActionPerformed(evt);
            }
        });

        deleteSongBtn.setText("Διαγραφή Τραγουδιού");
        deleteSongBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteSongBtnActionPerformed(evt);
            }
        });

        org.jdesktop.swingbinding.JTableBinding jTableBinding = org.jdesktop.swingbinding.SwingBindings.createJTableBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, songList, table);
        org.jdesktop.swingbinding.JTableBinding.ColumnBinding columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${title}"));
        columnBinding.setColumnName("Τίτλος");
        columnBinding.setColumnClass(String.class);
        columnBinding.setEditable(false);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${duration}"));
        columnBinding.setColumnName("Διάρκεια");
        columnBinding.setColumnClass(Integer.class);
        columnBinding.setEditable(false);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${albumId.title}"));
        columnBinding.setColumnName("Άλμπουμ");
        columnBinding.setColumnClass(String.class);
        columnBinding.setEditable(false);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${albumId.artistId}"));
        columnBinding.setColumnName("Καλλιτέχνης");
        columnBinding.setColumnClass(entities.Artist.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${albumId.musicGroupId}"));
        columnBinding.setColumnName("Συγκρότημα");
        columnBinding.setColumnClass(entities.MusicGroup.class);
        bindingGroup.addBinding(jTableBinding);
        jTableBinding.bind();
        jScrollPane2.setViewportView(table);

        jLabel1.setText("Συνολική Διάρκεια:");

        durationLabel.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        durationLabel.setText("0");
        durationLabel.setToolTipText("");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(durationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 108, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(saveButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel7)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(insertSongBtn)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(deleteSongBtn))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel2)
                            .addComponent(jLabel6))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(titleText, javax.swing.GroupLayout.DEFAULT_SIZE, 265, Short.MAX_VALUE)
                            .addComponent(dateTextField))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(14, 14, 14)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(titleText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(dateTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(28, 28, 28)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(insertSongBtn)
                    .addComponent(deleteSongBtn))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel7)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cancelButton)
                    .addComponent(saveButton)
                    .addComponent(jLabel1)
                    .addComponent(durationLabel))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        bindingGroup.bind();

        pack();
    }// </editor-fold>//GEN-END:initComponents
    
    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        closeDialog("Save");
    }//GEN-LAST:event_saveButtonActionPerformed

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        closeDialog("Cancel");
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void insertSongBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_insertSongBtnActionPerformed
        SongSearchForm dialog = new SongSearchForm();
        dialog.setVisible(true);
        if(dialog.getDialogResult().equals("Save"))
        {
            Song song = dialog.getEntity();
            if (songList.contains(song)) {
                ValidationHelper.showValidationError(this, "Το Τραγούδι αυτό υπάρχει ήδη στη Λίστα !");
            }
            else {
                songList.add(song);
                getTotalDuration();
            }
            
        }
    }//GEN-LAST:event_insertSongBtnActionPerformed

    private void deleteSongBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteSongBtnActionPerformed
        if (table.getSelectedRow() == -1){
            return;
        }
        Song song = songList.get(table.convertRowIndexToModel(table.getSelectedRow()));
        songList.remove(song);
        getTotalDuration();
    }//GEN-LAST:event_deleteSongBtnActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        closeDialog("Cancel");
    }//GEN-LAST:event_formWindowClosing

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton cancelButton;
    private javax.swing.JFormattedTextField dateTextField;
    private javax.swing.JButton deleteSongBtn;
    private javax.swing.JLabel durationLabel;
    private javax.persistence.EntityManager em;
    private entities.Playlist entity;
    private javax.swing.JButton insertSongBtn;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JButton saveButton;
    private java.util.List<entities.Song> songList;
    private javax.persistence.Query songQuery;
    private javax.swing.JTable table;
    private javax.swing.JTextField titleText;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables
}
